﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IlianaRuler.CPL;
using IlianaRuler.DAL;
using IlianaRuler.Utils;
using System.Threading;

namespace IlianaRuler
{
    class Program
    {
        static Communicator com = null;
        static ServerConfigData d = Business.GetServerConfig();
        static Wade.SSocket.SSocket ss = new Wade.SSocket.SSocket();
        static Dictionary<string, Wade.SSocket.Workstation> works = new Dictionary<string, Wade.SSocket.Workstation>();

        static void StartCommunicator(Object state)
        {
            if(com != null)
            {
                com.Close();
            }

            com = new Communicator();
            com.Disconnected += new Communicator.CommunicatorEvent((e) =>
            {
                ThreadPool.QueueUserWorkItem(StartCommunicator);
            });
            com.Connect(d.ServerIp, d.ServerPort, d.CustomerID, d.Password);
            Utility.Info(String.Format("已登录至 {0}:{1}", d.ServerIp, d.ServerPort));
        }

        static void Main(string[] args)
        {
            try
            {
                ss.enevtAddWorkstation += new Wade.SSocket.AddWorkstationEnevt(ss_enevtAddWorkstation);
                ss.enevtDeleteWorkstationEnevt += new Wade.SSocket.DeleteWorkstationEnevt(ss_enevtDeleteWorkstationEnevt);
                ss.enevtResultsFeedback += new Wade.SSocket.ResultsFeedbackEnevt(ss_enevtResultsFeedback);
                ss.enevtSocketSendObjectEnevt += new Wade.SSocket.SSocketSendObjectEnevt(ss_enevtSocketSendObjectEnevt);

                Console.Title = "Iliana rule server v1.0.0 build 20111111";
                StartCommunicator(null);
                ss.Start(d.localPort);
                while (true)
                {
                    string s = Console.ReadLine();
                    if (s == "exit")
                    {
                        break;
                    }
                    else if (s == "reset")
                    {
                        com.Close();
                        com = new Communicator();
                        com.Connect(d.ServerIp, d.ServerPort, d.CustomerID, d.Password);
                    }
                    else if (s == "cls")
                    {
                        Console.Clear();
                    }
                    #region 测试代码
                    else if (s == "r")
                    {
                        com.RegisterNode(1, "192.168.1.1", "tta", "001", true);
                    }
                    else if (s == "u")
                    {
                        com.UpdateNode(1, "192.168.1.1", "tta", "001");
                    }
                    else if (s == "d")
                    {
                        com.RemoveNode(1, "192.168.1.1", "tta");
                    }
                    else if (s == "t")
                    {
                        com.Timing(1, "192.168.1.1", "tta", TimingType.All);
                    }
                    else if (s == "s")
                    {
                        byte[] weekDays = new byte[] { 1, 3, 5 };
                        TacticRule[] rules = new TacticRule[] { 
                            new TacticRule(DateTime.Now, (float)1.0),
                            new TacticRule(DateTime.Now, (float)2.5)
                            };
                        string[] nodes = new string[] { "aaa", "bbb" };
                        com.SetTactics(1, "192.168.1.1", true, weekDays, rules, nodes);
                    }
                    else if (s == "c")
                    {
                        com.Control(1, "192.168.1.1", "tta", (float)2.0);
                    }
                    else if (s == "g")
                    {
                        com.GetStatus(1, "192.168.1.1", "tta");
                    }
                    else if (s == "l")
                    {
                        com.SelfChecking(1, "192.168.1.1", "tta", SelfCheckingType.Server);
                    }
                    #endregion
                }
                ss.Sotp();
            }
            catch(Exception e)
            {
                Utility.Error(e.Message);
                Console.ReadKey();
            }
        }

        static void ss_enevtSocketSendObjectEnevt(object obj)
        {
            Iliana.LSS.Command.SendCommand cmd = obj as Iliana.LSS.Command.SendCommand;
            if(cmd != null)
            {
                cmd.EvevtNodeRegister += new Iliana.LSS.Command.DelegateNodeRegister(cmd_EvevtNodeRegister);
                cmd.EvevtNodeDelete += new Iliana.LSS.Command.DelegateNodeDelete(cmd_EvevtNodeDelete);
                cmd.EvevtNodeControl += new Iliana.LSS.Command.DelegateNodeControl(cmd_EvevtNodeControl);
                cmd.EvevtNodeUpdate += new Iliana.LSS.Command.DelegateNodeUpdate(cmd_EvevtNodeUpdate);
                cmd.EvevtStrategySet += new Iliana.LSS.Command.DelegateStrategySet(cmd_EvevtStrategySet);
                cmd.EvevtDateTimeCheck += new Iliana.LSS.Command.DelegateDateTimeCheck(cmd_EvevtDateTimeCheck);
                cmd.EvevtHistoryDataRealTime += new Iliana.LSS.Command.DelegateAlarmHistoryDataRealTime(cmd_EvevtHistoryDataRealTime);
                cmd.EvevtHistoryDataRealTimeMeter += new Iliana.LSS.Command.DelegateAlarmHistoryDataRealTimeMeter(cmd_EvevtHistoryDataRealTimeMeter);
                cmd.EvevtRTUHistoryDataRealTimeMeter += new Iliana.LSS.Command.DelegateAlarmRTUHistoryDataRealTimeMeter(cmd_EvevtRTUHistoryDataRealTimeMeter);
                cmd.EvevtRTUNodeHistoryDataRealTime += new Iliana.LSS.Command.DelegateAlarmRTUNodeHistoryDataRealTime(cmd_EvevtRTUNodeHistoryDataRealTime);
                cmd.Manage();
            }
        }

        static void cmd_EvevtRTUNodeHistoryDataRealTime(Iliana.LSS.Model.mRTUNodeHistoryDataRealTime Data)
        {
            throw new NotImplementedException();
        }

        static void cmd_EvevtRTUHistoryDataRealTimeMeter(Iliana.LSS.Model.mRTUHistoryDataRealTimeMeter Data)
        {
            throw new NotImplementedException();
        }

        static void cmd_EvevtHistoryDataRealTimeMeter(Iliana.LSS.Model.HistoryDataRealTimeMeter Data)
        {
            //what's this?
            throw new NotImplementedException();
        }

        static void cmd_EvevtHistoryDataRealTime(Iliana.LSS.Model.HistoryDataRealTime Data)
        {
            //这个参数是什么意思？
            throw new NotImplementedException();
        }

        static void cmd_EvevtDateTimeCheck(Iliana.LSS.Command.Node Data)
        {
            //缺少校时类型参数
            //com.Timing((byte)Data.Type, Data.ServerIP, Data.NodeName, );
        }

        static void DoSetTactics(byte nodeType, string serverIp,
            bool valid, byte[] weekDays, TacticRule[] rules, string[] nodes)
        {
            com.SetTactics(nodeType, serverIp, valid, weekDays, rules, nodes);
        }

        static void cmd_EvevtStrategySet(Guid Data)
        {
            Business.SetTactics(Data, DoSetTactics);
        }

        static void cmd_EvevtNodeUpdate(Iliana.LSS.Command.Node Data)
        {
            com.UpdateNode((byte)Data.Type, Data.ServerIP, Data.NodeName, Data.NeruonID);
        }

        static void cmd_EvevtNodeControl(Iliana.LSS.Command.Node Data)
        {
            com.Control((byte)Data.Type, Data.ServerIP, Data.NodeName, Business.ParseState((byte)Data.Type, Data.NodeCommand));
        }

        static void cmd_EvevtNodeDelete(Iliana.LSS.Command.Node Data)
        {
            com.RemoveNode((byte)Data.Type, Data.ServerIP, Data.NodeName);
        }

        static void cmd_EvevtNodeRegister(Iliana.LSS.Command.Node Data)
        {
            com.RegisterNode((byte)Data.Type, Data.ServerIP,
                Business.CreateNodeName((byte)Data.Type, Data.ServerIP, Data.NeruonID),
                Data.NeruonID, Data.BindAlert
                );
        }

        static void ss_enevtResultsFeedback(string data)
        {
            //what's this?
            Utility.Info("收到反馈：" + data.ToString());
        }

        static void ss_enevtDeleteWorkstationEnevt(Wade.SSocket.Workstation work)
        {
            if(!works.ContainsKey(work.Ip))
            {
                works.Remove(work.Ip);
            }
        }

        static void ss_enevtAddWorkstation(Wade.SSocket.Workstation work)
        {
            if(!works.ContainsKey(work.Ip))
            {
                works.Add(work.Ip, work);
            }
        }
    }
}
